// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: chunhui

#pragma once

#include <cmath>
#include <cstdint>
#include <limits>

namespace interval_feed {

class TimeWeightedSpreadCalculator {
 public:
  TimeWeightedSpreadCalculator() {
    sum_ = 0;
    first_ts_ = 0;
    last_ts_ = 0;
    last_spread_ = 0;
  }

  void Update(int64_t ts, double spread) {
    if (spread > 0) {
      if (first_ts_ > 0) {
        sum_ += last_spread_ * static_cast<double>(ts - last_ts_);
        last_ts_ = ts;
      } else {
        first_ts_ = ts;
        last_ts_ = ts;
      }
      last_spread_ = spread;
    }
  }

  double GetSpread(int64_t interval_end_ts) const {
    if (first_ts_ == 0) {
      return std::numeric_limits<double>::quiet_NaN();
    }
    double sum = sum_ + last_spread_ * static_cast<double>(interval_end_ts - last_ts_);
    return sum / static_cast<double>(interval_end_ts - first_ts_);
  }

 private:
  double sum_;
  double last_spread_;
  int64_t first_ts_;
  int64_t last_ts_;
};

}  // namespace interval_feed
